<template>
    <div>
        <div class="canvas-box solid" ref="canvasBox">
            <!--用来和鼠标进行交互操作的canvas-->
            <canvas ref="canvas"></canvas>
            <!--存储已生成的点线，避免被清空-->
            <canvas
                ref="canvasSaveinfo"
                @mousemove="handleCanvasSaveMove"
                @mouseup="handleCanvasMouseUp"
                @mousedown="handleCanvasMouseDown"
            ></canvas>
        </div>
    </div>
</template>

<script setup>
import { onMounted, reactive, ref, nextTick, watch } from 'vue'
import { showMsg } from '@/assets/js/utils'
const props = defineProps({
    single: {
        type: Boolean,
        required: true,
    },
    completedDraw: {
        type: Boolean,
        required: false,
    }, //点线显/隐
    pointArr: {
        type: Array,
        default: () => {
            return []
        },
    }, //回显
    ratio: {
        type: Number,
    },
})
const canvas = ref(null)
const canvasBox = ref(null)
const canvasSaveinfo = ref(null)
const canvasForm = reactive({
    coincidentDistance: 10, // 重合距离
    oIndex: -1, //判断鼠标是否移动到起始点处，-1为否，1为是
    pointArr: [], //存放坐标的数组
    MovePointArr: [], //存放 拖拽移动时 坐标的数组
    pointX: '',
    pointY: '',
    ctxSave: '',
    canSave: '',
    ctx: '',
    can: '',
    lineColor: 'rgba(64, 158, 255, 1)',
    open: true,
    completedDraw: false, // 是否已经完成了绘图
    clickMove: false, //表明 正在拖拽的状态
    pointColorArr: [], //回显数据
})
const pointColorArr = ref(JSON.parse(JSON.stringify(props.pointArr)))
const emit = defineEmits(['finish'])
// 回显
function canvasFill(pointArr, color, houseName) {
    canvasForm.ctxSave.clearRect(
        0,
        0,
        canvasForm.ctxSave.width,
        canvasForm.ctxSave.height
    )
    canvasForm.ctxSave.beginPath()
    if (pointArr.length > 1) {
        canvasForm.ctxSave.moveTo(pointArr[0].x, pointArr[0].y)
        for (let i = 1; i < pointArr.length; i++) {
            canvasForm.ctxSave.lineTo(pointArr[i].x, pointArr[i].y)
        }
        canvasForm.ctxSave.fillStyle = `${color}B3` //填充颜色     ${color}6B   ${color}
        canvasForm.ctxSave.fill()
        canvasForm.ctxSave.stroke() //绘制
        canvasText(houseName, pointArr)
    }
}
watch(
    () => props.pointArr,
    (value) => {
        if (value[0].set_roi_region_name == '全屏检测') {
            value.map((item) => {
                item.set_roi_region_coordinate.forEach((item) => {
                    item.x = item.x * props.ratio
                    item.y = item.y * props.ratio
                })
                item.color = '#a0cfff'
                canvasFill(
                    item.set_roi_region_coordinate,
                    item.color,
                    item.set_roi_region_name
                )
            })
        }
    }
)
// 初始化画布
function initCanvas() {
    canvasForm.can = canvas.value
    canvasForm.can.width = canvasBox.value.clientWidth
    canvasForm.can.height = canvasBox.value.clientHeight
    canvasForm.ctx = canvasForm.can.getContext('2d')
    canvasForm.ctx.strokeStyle = canvasForm.lineColor //线条颜色
    canvasForm.ctx.fillStyle = 'rgba(64, 158, 255,0.1)' //填充颜色
    canvasForm.ctx.lineWidth = 4 //线条粗细
    canvasForm.ctx.globalAlpha = 0.7 //半透明
    canvasForm.canSave = canvasSaveinfo.value
    canvasForm.canSave.width = canvasBox.value.clientWidth
    canvasForm.canSave.height = canvasBox.value.clientHeight
    canvasForm.ctxSave = canvasForm.canSave.getContext('2d')
    canvasForm.ctxSave.strokeStyle = canvasForm.lineColor //线条颜色
    canvasForm.ctxSave.fillStyle = 'rgba(64, 158, 255,0.1)' //填充颜色
    canvasForm.ctxSave.lineWidth = 4 //线条粗细
    canvasForm.ctxSave.globalAlpha = 0.7 //半透明
    pointColorArr.value.map((item) => {
        item.set_roi_region_coordinate.forEach((xitem) => {
            xitem.x = xitem.x * props.ratio
            xitem.y = xitem.y * props.ratio
        })
        item.set_roi_region_coordinate.push(item.set_roi_region_coordinate[0])
        item.color = '#a0cfff'
        canvasFill(
            item.set_roi_region_coordinate,
            item.color,
            item.set_roi_region_name
        )
    })
}
// 文字
function canvasText(text, point) {
    canvasForm.ctxSave.font = '18px Consolas' //字体样式的属性
    canvasForm.ctxSave.textAlign = 'center' //设置文本对齐方式
    canvasForm.ctxSave.textBaseline = 'middle' //文本基线
    canvasForm.ctxSave.fillStyle = 'red' //字体颜色
    if (point[0].x == 0) {
        canvasForm.ctxSave.fillText(text, point[0].x + 100, point[0].y + 50) //绘制文字
    } else {
        canvasForm.ctxSave.fillText(text, point[0].x + 10, point[0].y + 10) //绘制文字
    }
    canvasForm.ctxSave.arc(point[0].x, point[0].y, 3, 0, Math.PI * 2) //基准点
}
function handleCanvasMouseUp() {
    if (canvasForm.clickMove) {
        canvasForm.clickMove = false
        canvasForm.pointArr = canvasForm.MovePointArr
        // canvasForm.$emit('finish', canvasForm.pointArr)
    }
}
// 点击画点
function handleCanvasMouseDown(e) {
    if (!props.completedDraw) {
        return
    }
    if (e.offsetX || e.layerX) {
        canvasForm.pointX = e.offsetX == undefined ? e.layerX : e.offsetX
        canvasForm.pointY = e.offsetY == undefined ? e.layerY : e.offsetY
        let piX, piY
        if (canvasForm.oIndex > 0 && canvasForm.pointArr.length > 0) {
            piX = canvasForm.pointArr[0].x
            piY = canvasForm.pointArr[0].y
            //画点
            makearc(
                canvasForm.ctx,
                piX,
                piY,
                GetRandomNum(2, 2),
                0,
                180,
                'rgba(102,168,255,1)'
            )
            canvasForm.pointArr.push({ x: piX, y: piY })
            canvasSave(canvasForm.pointArr) //保存点线同步到另一个canvas
            saveCanvas() //生成画布
        } else {
            piX = canvasForm.pointX
            piY = canvasForm.pointY
            makearc(
                canvasForm.ctx,
                piX,
                piY,
                GetRandomNum(2, 2),
                0,
                180,
                'rgba(102,168,255,1)'
            )
            canvasForm.pointArr.push({ x: piX, y: piY })
            canvasSave(canvasForm.pointArr) //保存点线同步到另一个canvas
        }
    }
}
// 移动画线
function handleCanvasSaveMove(e) {
    if (!props.completedDraw) {
        return
    }
    if (e.offsetX || e.layerX) {
        canvasForm.pointX = e.offsetX == undefined ? e.layerX : e.offsetX
        canvasForm.pointY = e.offsetY == undefined ? e.layerY : e.offsetY
        let piX, piY
        /*清空画布*/
        canvasForm.ctx.clearRect(
            0,
            0,
            canvasForm.can.width,
            canvasForm.can.height
        )
        /*鼠标下跟随的圆点*/
        makearc(
            canvasForm.ctx,
            canvasForm.pointX,
            canvasForm.pointY,
            GetRandomNum(4, 4),
            0,
            180,
            'rgba(102,168,255,1)'
        )

        if (canvasForm.pointArr.length > 0) {
            if (
                canvasForm.pointX > canvasForm.pointArr[0].x - 15 &&
                canvasForm.pointX < canvasForm.pointArr[0].x + 15 &&
                canvasForm.pointY > canvasForm.pointArr[0].y - 15 &&
                canvasForm.pointY < canvasForm.pointArr[0].y + 15
            ) {
                if (canvasForm.pointArr.length > 1) {
                    piX = canvasForm.pointArr[0].x
                    piY = canvasForm.pointArr[0].y
                    canvasForm.ctx.clearRect(
                        0,
                        0,
                        canvasForm.can.width,
                        canvasForm.can.height
                    )
                    makearc(
                        canvasForm.ctx,
                        piX,
                        piY,
                        GetRandomNum(4, 4),
                        0,
                        180,
                        'rgba(102,168,255,1)'
                    )
                    canvasForm.oIndex = 1
                }
            } else {
                piX = canvasForm.pointX
                piY = canvasForm.pointY
                canvasForm.oIndex = -1
            }
            /*开始绘制*/
            canvasForm.ctx.beginPath()
            canvasForm.ctx.moveTo(
                canvasForm.pointArr[0].x,
                canvasForm.pointArr[0].y
            )
            if (canvasForm.pointArr.length > 1) {
                for (let i = 1; i < canvasForm.pointArr.length; i++) {
                    canvasForm.ctx.lineTo(
                        canvasForm.pointArr[i].x,
                        canvasForm.pointArr[i].y
                    )
                }
            }
            canvasForm.ctx.lineTo(piX, piY)
            canvasForm.ctx.fillStyle = 'rgba(161,195,255,1)' //填充颜色
            canvasForm.ctx.fill() //填充
            canvasForm.ctx.stroke() //绘制
        }
    }
}
// 存储已生成的点线
function canvasSave(pointArr) {
    // canvasForm.ctxSave.clearRect(
    //     0,
    //     0,
    //     canvasForm.ctxSave.width,
    //     canvasForm.ctxSave.height
    // )
    // canvasForm.ctxSave.beginPath()
    // if (pointArr.length > 1) {
    //     canvasForm.ctxSave.moveTo(pointArr[0].x, pointArr[0].y)
    //     for (let i = 1; i < pointArr.length; i++) {
    //         canvasForm.ctxSave.lineTo(pointArr[i].x, pointArr[i].y)
    //         canvasForm.ctxSave.fillStyle = 'rgba(161,195,255,0.8)' //填充颜色
    //         //ctxSave.fill();
    //         canvasForm.ctxSave.stroke() //绘制
    //     }
    //     canvasForm.ctxSave.closePath()
    // }
    canvasForm.ctxSave.clearRect(
        0,
        0,
        canvasForm.ctxSave.width,
        canvasForm.ctxSave.height
    )
    canvasForm.ctxSave.beginPath()
    if (pointArr.length > 1) {
        canvasForm.ctxSave.moveTo(pointArr[0].x, pointArr[0].y)
        for (let i = 1; i < pointArr.length; i++) {
            canvasForm.ctxSave.lineTo(pointArr[i].x, pointArr[i].y)
            canvasForm.ctxSave.fillStyle = 'rgba(161,195,255,0.2)' //填充颜色
            //canvasForm.ctxSave.fill();
            canvasForm.ctxSave.stroke() //绘制
        }
        canvasForm.ctxSave.closePath()
    }
    // console.log('存储已生成的点线', pointArr)
    //判断最后一个点重合则结束绘制
    if (pointArr.length > 1) {
        let { 0: a, [pointArr.length - 1]: b } = pointArr
        if (a.x == b.x && b.y == b.y) {
            console.log('结束绘制')
        }
    }
}
/*生成画布 结束绘画*/
function saveCanvas() {
    if (canvasForm.pointArr.length <= 3) {
        showMsg('检查区域至少为三边形，请重新绘制', 'error')
        revoke()
        return
    }
    canvasForm.ctx.clearRect(0, 0, canvasForm.can.width, canvasForm.can.height)
    canvasForm.ctxSave.closePath() //结束路径状态，结束当前路径，如果是一个未封闭的图形，会自动将首尾相连封闭起来
    canvasForm.ctxSave.fill() //填充
    canvasForm.ctxSave.stroke() //绘制
    // canvasForm.completedDraw = true
    emit('finish', canvasForm.pointArr.slice(1))
    canvasForm.pointArr = []
}
/*验证canvas画布是否为空函数*/
// function isCanvasBlank(canvas) {
//     let blank = document.createElement('canvas') //创建一个空canvas对象
//     blank.width = canvas.width
//     blank.height = canvas.height
//     return canvas.toDataURL() == blank.toDataURL() //为空 返回true
// }
/*canvas生成圆点*/
function GetRandomNum(Min, Max) {
    let Range = Max - Min
    let Rand = Math.random()
    return Min + Math.round(Rand * Range)
}
// 画点
function makearc(ctx, x, y, r, s, e, color) {
    ctx.clearRect(0, 0, 199, 202) //清空画布
    ctx.beginPath()
    ctx.fillStyle = color
    ctx.arc(x, y, r, s, e)
    ctx.fill()
}
// 重置
function reset() {
    canvasForm.ctx.clearRect(0, 0, canvasForm.can.width, canvasForm.can.height)
    canvasForm.ctxSave.clearRect(
        0,
        0,
        canvasForm.canSave.width,
        canvasForm.canSave.height
    )
    canvasForm.pointArr = []
    canvasForm.completedDraw = false
    canvasForm.open = false
}
// 撤销上一步
function revoke() {
    if (canvasForm.open && props.single) {
        reset()
    }
    canvasForm.ctx.clearRect(0, 0, canvasForm.can.width, canvasForm.can.height)
    canvasForm.ctxSave.clearRect(
        0,
        0,
        canvasForm.canSave.width,
        canvasForm.canSave.height
    )
    canvasForm.pointArr.pop()
    canvasForm.pointArr.map((item) => {
        let _e = {
            layerX: item.x,
            layerY: item.y,
        }
        handleCanvasSaveMove(_e)
    })
}
// function isExistIntersection() {
//     let result = false
//     for (let i = 0; i < canvasForm.pointArr.length - 1; i++) {
//         let a = canvasForm.pointArr[i]
//         let b = canvasForm.pointArr[i + 1]
//         for (let j = 0; j < canvasForm.pointArr.length - 1; j++) {
//             if (i == j) {
//                 continue
//             }
//             let c = canvasForm.pointArr[j]
//             let d = canvasForm.pointArr[j + 1]
//             result = isIntersection(a, b, c, d)
//             if (result) {
//                 return result
//             }
//         }
//     }
//     return result
// }
// //判断两个线段是否相交
// function isIntersection(a, b, c, d) {
//     /** 1 解线性方程组, 求线段交点. **/
//     // 如果分母为0 则平行或共线, 不相交
//     let denominator = (b.y - a.y) * (d.x - c.x) - (a.x - b.x) * (c.y - d.y)
//     if (denominator == 0) {
//         return false
//     }

//     // 线段所在直线的交点坐标 (x , y)
//     let x =
//         ((b.x - a.x) * (d.x - c.x) * (c.y - a.y) +
//             (b.y - a.y) * (d.x - c.x) * a.x -
//             (d.y - c.y) * (b.x - a.x) * c.x) /
//         denominator
//     let y =
//         -(
//             (b.y - a.y) * (d.y - c.y) * (c.x - a.x) +
//             (b.x - a.x) * (d.y - c.y) * a.y -
//             (d.x - c.x) * (b.y - a.y) * c.y
//         ) / denominator

//     /** 2 判断交点是否在两条线段上 **/
//     if (
//         // 交点在线段1上
//         (x - a.x) * (x - b.x) < 0 &&
//         (y - a.y) * (y - b.y) < 0 &&
//         // 且交点也在线段2上
//         (x - c.x) * (x - d.x) < 0 &&
//         (y - c.y) * (y - d.y) < 0
//     ) {
//         return true
//     }
//     //否则不相交
//     return false
// }
onMounted(() => {
    nextTick(() => {
        initCanvas()
    })
})
// 导出供父组件调用
defineExpose({
    reset,
})
</script>

<style lang="scss" scoped>
.canvas-box {
    position: relative;
    width: 100%;
    height: 100%;
}
.canvas-box canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    // background: paleturquoise;
}
</style>
